package com.thz.houserental.infrastructure.advice.exception;

import com.thz.houserental.infrastructure.advice.response.CommonResponse;
import com.thz.houserental.infrastructure.exception.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolationException;
import javax.xml.bind.ValidationException;

/**
 * 全局异常捕获处理
 * 操作失败返回拦截
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionAdvice {
    
    @ExceptionHandler(value = Exception.class)
    public CommonResponse<String> handleException(
            HttpServletRequest req, Exception ex,
            HttpServletResponse httpResponse
    ) {

        CommonResponse<String> response = new CommonResponse<>(
                500, "untracked error: " + ex.getMessage() 
        );
        httpResponse.setStatus(500);
        log.error("service has error: [{}]", ex.getMessage(), ex);
        return response;
    }
    
    @ExceptionHandler(value = ConstraintViolationException.class) 
    public CommonResponse<String> handleValidationException(
            HttpServletRequest req, ConstraintViolationException ex,
            HttpServletResponse httpResponse) {
        CommonResponse<String> response = new CommonResponse<>();
        httpResponse.setStatus(HttpStatus.BAD_REQUEST.value());
        response.setCode(HttpStatus.BAD_REQUEST.value());
        response.setMessage(ex.getMessage());
        
        return response;
    }

    @ExceptionHandler(value = HttpException.class)
    public CommonResponse<String> handleHttpException(
            HttpServletRequest req, 
            HttpException ex,
            HttpServletResponse httpResponse
    ) {
        CommonResponse<String> response = new CommonResponse<>(
                500, "untracked error: http exception"
        );
        response.setCode(ex.getCode());
        response.setMessage(ex.getMessage());
        httpResponse.setStatus(500);
        log.error("service has error: [{}]", ex.getMessage(), ex);
        return response;
    }

    @ExceptionHandler(value = NotFoundException.class)
    public CommonResponse<String> handleNotFoundException(
            HttpServletRequest req, 
            NotFoundException ex,
            HttpServletResponse httpResponse
    ) {

        CommonResponse<String> response = new CommonResponse<>(
                404, "notfound"
        );
        response.setCode(ex.getCode());
        response.setMessage(ex.getMessage());
        httpResponse.setStatus(HttpStatus.NOT_FOUND.value());
        log.error("service has error: [{}]", ex.getMessage(), ex);
        return response;
    }

    @ExceptionHandler(value = ParameterException.class)
    public CommonResponse<String> handleParameterException(
            HttpServletRequest req, 
            ParameterException ex,
            HttpServletResponse httpResponse
    ) {

        CommonResponse<String> response = new CommonResponse<>(
                400, "请求参数错误"
        );
        response.setCode(ex.getCode());
        response.setMessage(ex.getMessage());
        httpResponse.setStatus(HttpStatus.BAD_REQUEST.value());
        log.error("service has error: [{}]", ex.getMessage(), ex);
        return response;
    }

    //TODO token过期处理
    @ExceptionHandler(value = TokenExpiredException.class)
    public CommonResponse<String> handleTokenExpiredException (
            HttpServletRequest req, Exception ex
    ) {
        CommonResponse<String> response = new CommonResponse<>(
                -1, "untracked error"
        );
        response.setData(ex.getMessage());
        log.error("service has error: [{}]", ex.getMessage(), ex);
        return response;
    }

    @ExceptionHandler(value = ForbiddenException.class)
    public CommonResponse<String> handleForbiddenException(
            HttpServletRequest req, 
            ForbiddenException ex,
            HttpServletResponse httpResponse
    ) {

        CommonResponse<String> response = new CommonResponse<>(
                403, "untracked error"
        );
        response.setCode(ex.getCode());
        response.setMessage(ex.getMessage());
        httpResponse.setStatus(HttpStatus.FORBIDDEN.value());
        log.error("service has error: [{}]", ex.getMessage(), ex);
        return response;
    }
    
    
    
    
}
